﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Netra
{
    class TextUserInterface
    {
        private Galaxy galaxy;

        public TextUserInterface(Galaxy _galaxy)
        {
            galaxy = _galaxy;
        }

        public void Run()
        {
            MainMenu();
        }

        private void MainMenu()
        {
            Console.WriteLine("Main menu");

            //Delete this part
            {
                //var trrt = new TradeRoute();
                //var ctr = new CreateTradeRouteForm(galaxy,trrt);
                //ctr.ShowDialog();
                //DisplayTradeRoute(trrt);
                //return;
            }
            //Deletion end

            string command;
            bool koniec = false;
            while (!koniec && ((command = Console.ReadLine()) != null))
            {
                switch (command)
                {
                    case "galaxy":
                    case "g":
                        GalaxyMenu();
                        break;
                    case "n":
                    case "next":
                        galaxy.NextTurn();
                        break;
                    case "fleetlist":
                    case "fl":
                        DisplayFleets();
                        break;
                    case "fleets":
                    case "f":
                        {
                            DisplayFleets();
                            Console.WriteLine("Pick number");
                            string snum = Console.ReadLine();
                            int num = Convert.ToInt32(snum) - 1;
                            try
                            {
                                FleetMenu(galaxy.Fleets[num]);
                            }
                            catch (ArgumentOutOfRangeException)
                            {
                                Console.WriteLine("Invalid number. Type 'list' to get valid planet numbers.");
                            }
                        }
                        break;
                    case "exit":
                    case "q":
                        koniec = true;
                        break;
                }
                Console.WriteLine("Main menu");
            }

            Console.WriteLine("Exit");
        }

        private void GalaxyMenu()
        {

            string command;
            Console.WriteLine("Galaxy menu");
            DisplayPlanets();
            bool koniec = false;
            while (!koniec&&((command=Console.ReadLine())!=null))
            {
                switch (command)
                {
                    case "l":
                    case "list":
                        {
                            DisplayPlanets();
                            //int i = 1;
                            //foreach (Planet p in galaxy.Planets)
                            //{
                            //    Console.WriteLine("{0}): {1}", i, p.Name);
                            //    i++;
                            //}
                        }
                        break;
                    case "planet":
                    case "p":
                        {
                            List<string> list = DisplayPlanets();
                            Console.WriteLine("Which number?");
                            string snum = Console.ReadLine();
                            int num = Convert.ToInt32(snum)-1;
                            try
                            {
                                //PlanetMenu(galaxy.Planets[num]);
                                var planet_info = new PlanetInfo(galaxy.PlanetsByName[list[num]]);
                                //planet_info.ShowDialog();
                            }
                            catch (ArgumentOutOfRangeException)
                            {
                                Console.WriteLine("Invalid number. Type 'list' to get valid planet numbers.");
                            }
                        }
                        break;
                    case "q":
                    case "exit":
                        koniec = true;
                        break;
                }
                Console.WriteLine("Galaxy menu");
            }

            Console.WriteLine("Exit");
       }

       private void PlanetMenu(Planet planet)
       {

           string command;
           Console.WriteLine("Planet {0}", planet.Name);
           bool koniec = false;
           while (!koniec && ((command = Console.ReadLine()) != null))
           {
               switch (command)
               {
                   case "merch":
                   case "m":
                       {
                           Console.WriteLine("{0}: Merchandises", planet.Name);
                           DisplayStore(planet.store);
                       }
                       break;
                   case "q":
                   case "exit":
                       koniec = true;
                       break;
               }
               Console.WriteLine("Planet {0}", planet.Name);
           }

           Console.WriteLine("Exit");

       }

       private void DisplayStore(Store store)
       {
           string format;
           List<Merch> offered = store.OfferedWares();
           List<Merch> purchased = store.PurchasedWares();

           Console.WriteLine("Planet sells:");
           format = "{0,-20} {1,10} {2,10} {3,10}";
           Console.WriteLine(format, "Merchandise", "Quantity", "Sell price", "Production");
           foreach (Merch ware in offered)
           {
               Console.WriteLine(format, ware.Name, store.MaxSellQuantity(ware), store.SellPrice(ware), store.Production(ware));
           }

           Console.WriteLine("Planet buys:");
           format = "{0,-20} {1,10} {2,10} {3,10}";
           Console.WriteLine(format, "Merchandise", "Quantity", "Buy price", "Consumption");
           foreach (Merch ware in purchased)
           {
               Console.WriteLine(format, ware.Name, store.MaxBuyQuantity(ware), store.BuyPrice(ware), store.Consumption(ware));
           }

           //Console.WriteLine(store.ToString());
           //format = "{0,-20} {1,10} {2,10} {3,10} {4,10}";
           //Console.WriteLine(format, "Merchandise", "To sell", "To buy", "Sell price", "Buy price");
           //foreach (Merch ware in Merch.Goods)
           //{
           //    Console.WriteLine(format, ware.Name, store.MaxSellQuantity(ware), store.MaxBuyQuantity(ware), store.SellPrice(ware), store.BuyPrice(ware));
           //}
       }

       private List<string> DisplayPlanets()
       {
           var list = new List<string>();
           int i = 1;
           foreach (Planet p in galaxy.Planets)
           {
               Console.WriteLine("{0}): {1} {2}", i, p.Name,p.Pos);
               list.Add(p.Name);
               i++;
           }
           return list;
       }

       private void FleetMenu(Fleet fleet)
       {
           string command;
           Console.WriteLine("Fleet {0} at {1}", fleet.Name, fleet.Pos);
           bool koniec = false;

           //DisplayFleets();

           while (!koniec && ((command = Console.ReadLine()) != null))
           {
               switch (command)
               {
                   case "go":
                       {
                           Planet dest;
                           if ((dest=ChoosePlanet())!=null)
                           {
                               Console.WriteLine("Destination {0}", dest.Name);
                               fleet.Aim = dest;
                           }
                       }
                       break;
                   case "l":
                       {
                           DisplayFleet(fleet);
                       }
                       break;
                   case "tr":
                       {
                           TradeRoute tr;
                           if (fleet.IsTradeRouteAssigned())
                           {
                               tr = fleet.GetTradeRoute();
                           }
                           else
                           {
                               tr = new TradeRoute();
                           }

                           var ctr = new CreateTradeRouteForm(galaxy,tr);
                           ctr.ShowDialog();
                           DisplayTradeRoute(tr);

                           fleet.AssignTradeRoute(tr);

                           /*
                           TradeRoute tr = CreateTradeRoute();
                           if (tr != null)
                           {
                               DisplayTradeRoute(tr);
                               fleet.AssignTradeRoute(tr);
                           }
                           else
                               Console.WriteLine("Trade route cancelled");
                            */
                       }
                       break;
                   case "q":
                   case "exit":
                       koniec = true;
                       break;
               }
               Console.WriteLine("Fleets");
           }

           Console.WriteLine("Exit");
       }

       private void DisplayFleets()
       {
           Console.WriteLine("Available fleets");
           int i = 1;
           foreach (Fleet f in galaxy.Fleets)
           {
               Console.Write("{0}): {1}, at {2},", i, f.Name,f.Pos);
               if (f.Moving())
                   Console.WriteLine(" heading to {0}", f.Aim.Name);
               else
                   Console.WriteLine(" stopped");
               i++;
           }
       }

       private void DisplayFleet(Fleet fleet)
       {
           Console.WriteLine("Fleet {0}, at {1}", fleet.Name, fleet.Pos);
           Dictionary<Merch, int> merch_quant=fleet.GetMerchQuant();

           Console.WriteLine("Cargo:");
           foreach(KeyValuePair<Merch,int> elem in merch_quant)
           {
               Console.WriteLine("{0}: {1}", elem.Key.Name, elem.Value);
           }
       }

       private Planet ChoosePlanet()
       {
           List<string> list=DisplayPlanets();
           Console.WriteLine("Which number (q to finish)?");
           string snum = Console.ReadLine();
           if (snum == "q")
               return null;

           int num = Convert.ToInt32(snum) - 1;
           try
           {
               return galaxy.PlanetsByName[list[num]];
           }
           catch (ArgumentOutOfRangeException)
           {
               Console.WriteLine("Invalid number. Type 'list' to get valid planet numbers.");
               return null;
           }
       }

       private TradeRoute CreateTradeRoute()
       {
           Planet planeta;
           TradeRoute trrt=new TradeRoute();
           while ((planeta = ChoosePlanet()) != null)
           {
               int i;
               Dictionary<Merch, int> trades=new Dictionary<Merch,int>();

               while (true)
               {
                   DisplayStore(planeta.store);

                   for (i = 0; i < Merch.Goods.Count; i++)
                   {
                       Console.WriteLine("{0}) {1}", i,Merch.Goods[i].Name);
                   }
                   string snum = Console.ReadLine();
                   if (snum == "q")
                   {
                       break;
                   }
                   Console.WriteLine("s - sell, b - buy:");
                   string stran = Console.ReadLine();
                   Console.WriteLine("quantity:");
                   string squant = Console.ReadLine();
                   i = Convert.ToInt32(snum);
                   int quant = Convert.ToInt32(squant);

                   try
                   {
                       if (stran == "b")
                       {
                           trades[Merch.Goods[i]] = quant;
                       }
                       else if (stran == "s")
                       {
                           trades[Merch.Goods[i]] = -quant;
                       }
                       else
                       {
                           Console.WriteLine("Invalid transaction type");
                       }
                   }
                   catch (ArgumentOutOfRangeException)
                   {
                        Console.WriteLine("Invalid number.");
                   }
               }

               trrt.Add(planeta, trades);

           }

           if (trrt.Length == 0)
           {
               return null;
           }
           else
           {
               return trrt;
           }
       }

       private void DisplayTradeRoute(TradeRoute tr)
       {
           List<TradeRoute.Element> path = tr.Path;
           foreach (TradeRoute.Element elem in path)
           {
               Console.WriteLine("{0}", elem.Planet.Name);
               foreach (KeyValuePair<Merch, int> tra in elem.Deals)
               {
                   if (tra.Value >= 0)
                   {
                       Console.WriteLine("Buy {0}, {1}", tra.Key.Name, tra.Value);
                   }
                   else
                   {
                       Console.WriteLine("Sell {0}, {1}", tra.Key.Name, -tra.Value);
                   }
               }
           }
       }
    }



}
